package com.alibaba.citrus.cr.forecast.facade.service;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.CalendarCompareUtil;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderLineQueryRepository;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderLineWriteRepository;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderQueryRepository;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.EmployeeGetCurrentLoginResponse;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.crforecastsales.api.forecastorderlinewrite.dto.UpdateAnalysisDateByBizRequest;
import com.epoch.app.crforecastsales.api.forecastorderlinewrite.dto.UpdateBizFeaturesDateByBizRequest;
import com.epoch.app.crforecastsales.api.forecastorderlinewrite.dto.UpdateLineByBizIdRequest;
import com.epoch.app.crforecastsales.api.forecastorderlinewrite.service.ForecastOrderLineWriteService;
import com.epoch.app.crforecastsales.dto.request.DeleteForecastLineDetailRequest;
import com.epoch.app.crforecastsales.dto.request.LoseFocusSaveForecastLineOrderRequest;
import com.epoch.app.crforecastsales.dto.request.UpdateForecastQtyRequest;
import com.epoch.app.crforecastsales.dto.response.DeleteForecastLineDetailReponse;
import com.epoch.app.crforecastsales.dto.response.LoseFocusSaveForecastLineOrderReponse;
import com.epoch.app.crforecastsales.enums.ForecastStatusEnum;
import com.epoch.app.crforecastsales.model.dto.BatchUpdateForAnalysisDTO;
import com.epoch.app.crforecastsales.model.dto.DeleteLineWithRelease;
import com.epoch.app.crforecastsales.model.dto.UpdateForAnalysisDataDTO;
import com.epoch.app.crforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.crforecastsales.sdo.ForecastOrderSDO;
import com.epoch.app.crplatformenhance.api.strategyquery.service.StrategyQueryService;
import com.epoch.app.crplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.crplatformenhance.inventoryallotlinewrite.service.InventoryAllotLineWriteService;
import com.epoch.app.crplatformenhance.model.dto.BatchReleaseDailyInvRequest;
import com.epoch.app.crplatformenhance.model.dto.MoreConditionQueryRequest;
import com.epoch.app.crplatformenhance.model.dto.MoreConditionQueryResponse;
import com.epoch.app.crplatformenhance.model.dto.ReleaseDailyInvRequest;
import com.epoch.app.crplatformenhance.model.enums.RuleTypeEnum;
import com.epoch.app.crplatformenhance.sdo.DimensionSDO;
import com.epoch.app.crplatformenhance.sdo.StrategySDO;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: qiaojiange
 * @create: 2021/09/15
 * @Description 请描述类的业务用途
 */
@Service
@Primary
public class ForecastOrderLineWriteServiceImpl implements ForecastOrderLineWriteService {
    private static final Log log = Log.getLogger(ForecastOrderLineWriteServiceImpl.class);
    public static final String ALLOTLINEID = "allotlineid";
    public static final String DISINTEGRATION_QTY = "disintegrationQty";
    //能确认生产销售单的预报单据状态
    public static final List<Integer> CAN_DEL_FORECAST_STATUS = Lists.newArrayList(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue(),ForecastStatusEnum.DRAFT.getNumValue());
    @Resource
    private ForecastOrderLineWriteRepository forecastOrderLineWriteRepository;
    @Resource
    private ForecastOrderLineQueryRepository forecastOrderLineQueryRepository;

    @Resource
    private ForecastOrderQueryRepository forecastOrderQueryRepository;
    @Resource
    private InventoryAllotLineWriteService inventoryAllotLineWriteService;

    @Resource
    private  StrategyQueryService strategyQueryService;
    @Resource
    private  BcOrderService bcOrderService;

    @Override
    public Result<Integer> updateForecastQty(UpdateForecastQtyRequest updateForecastQtyRequest) {
//        Integer integer = forecastOrderLineWriteService.updateForecastQty(updateForecastQtyRequest);

        return Result.success(0);
    }
    /*
        删除子订单 王成
     */
    @Override
    @FacadeInvoker
    public Result<DeleteForecastLineDetailReponse> deleteForecastLine(DeleteForecastLineDetailRequest request) {
        DeleteForecastLineDetailReponse deleteForecastLineDetailReponse = new DeleteForecastLineDetailReponse();
        Integer count = forecastOrderLineWriteRepository.deleteForecastLine(request);
        deleteForecastLineDetailReponse.setCount(count);
        return Result.success(deleteForecastLineDetailReponse);
    }
    /*
    失焦点保存 王成
     */
    @Override
    @FacadeInvoker
    public Result<LoseFocusSaveForecastLineOrderReponse> loseFocusSaveForecastLineOrder(
        LoseFocusSaveForecastLineOrderRequest request) {
        LoseFocusSaveForecastLineOrderReponse loseFocusSaveForecastLineOrderReponse = new LoseFocusSaveForecastLineOrderReponse();
        Integer count = forecastOrderLineWriteRepository.loseFocusSave(request);
        loseFocusSaveForecastLineOrderReponse.setCount(count);
        return Result.success(loseFocusSaveForecastLineOrderReponse);
    }


    @Override
    @FacadeInvoker
    public Result<DeleteForecastLineDetailReponse> deleteForecastLineWithRelease(DeleteLineWithRelease deleteLineWithRelease){
        if (Objects.isNull(deleteLineWithRelease)|| CollectionUtils.isEmpty(deleteLineWithRelease.getIds())){
            throw new FunctionException("OTS-04-001-00-15-049","请求参数不能为空！");
        }
        List<String> ids = deleteLineWithRelease.getIds().stream().map(Objects::toString).collect(Collectors.toList());

        List<ForecastOrderLineSDO> orderLineSDOList = forecastOrderLineQueryRepository.batchForecastOrderLineList(ids);

        if (CollectionUtils.isEmpty(orderLineSDOList)){
            throw new FunctionException("OTS-04-001-00-15-050","查询预报子单列表失败！");
        }

        //待回复状态 业务员角色需要验证有效性检查
        String mainOrderId = orderLineSDOList.get(0).getMainOrderId();
        ForecastOrderSDO forecastOrderSDO = forecastOrderQueryRepository.queyrDetail(mainOrderId);

        //获取当前登录人信息
        EmployeeGetCurrentLoginResponse currentLoginResponse = bcOrderService.employeeGetCurrentLogin();
         //待回复状态的保存需要效验有效性策略 20220217需求 待回复状态可以编辑(add by myw) 只有业务员角色才效验待回复状态的有效性检查
        if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())&&currentLoginResponse.getOnlySales()){
            //判断待回复状态的订单是否可以保存
            //根据查询结果 判断是时间段还是截止时间 是拦截还是提示
            //如果是拦截的话不允许保存  提示的话可以保存
            MoreConditionQueryRequest moreConditionQueryRequest = new MoreConditionQueryRequest();
            moreConditionQueryRequest.setStrategyType(StrategyTypeEnum.VALIDITY.getCode());
            moreConditionQueryRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());//forecastOrderSDO.getOrganizationCode()
            moreConditionQueryRequest.setChannelCode(forecastOrderSDO.getChannelCode());//forecastOrderSDO.getChannelCode()
            moreConditionQueryRequest.setWareHouseCode(forecastOrderSDO.getWareHouseCode());
            log.info("ForecastOrderEntity|save|"+forecastOrderSDO.getOrderBizId()+"|查询有效期校验|request|", JSONObject.toJSONString(moreConditionQueryRequest));
            Result<MoreConditionQueryResponse> moreConditionQueryResponseResult = strategyQueryService.moreConditionQuery(moreConditionQueryRequest);
            log.info("ForecastOrderEntity|save|"+forecastOrderSDO.getOrderBizId()+"|查询有效期校验|result|", JSONObject.toJSONString(moreConditionQueryResponseResult));
            MoreConditionQueryResponse moreConditionQueryResponse = moreConditionQueryResponseResult.getResult();

            if (Objects.nonNull(moreConditionQueryResponse)) {
                StrategySDO strategySDO = moreConditionQueryResponse.getStrategySDO();
                List<DimensionSDO> dimensionSDOList = strategySDO.getDimensionSDOList();
                DimensionSDO dimensionSDO = dimensionSDOList.get(0);
                //获取规则
                String value = dimensionSDO.getRuleName();
                if (StringUtils.equals(RuleTypeEnum.TIME_POINT.getCode(), value)) {
                    //获取规则值
                    String ruleValue = dimensionSDO.getRuleValue();
                    //判断截止时间是否满足 当前时间大于截止时间 不满足
                    boolean compare = CalendarCompareUtil.compareDateTimes(null, ruleValue);
                    if (compare) {
                        Boolean executeAction = dimensionSDO.getExecuteAction();
                        if (executeAction) {
                            throw new FunctionException("OTS-04-001-00-15-048");
                            // return "该时间范围内不允许修改，请联系订单员修改";
                        }
                    }
                }
                if (StringUtils.equals(RuleTypeEnum.TIME_FRAME.getCode(), value)) {
                    String ruleValue = dimensionSDO.getRuleValue();
                    String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]") ).replace("\"", "");
                    String[] split = substring.split(",");
                    String ruleValueSplit = split[0];
                    String ruleValueSplit1 = split[1];
                    boolean compareDateTimes = CalendarCompareUtil.compareDateTimes(ruleValueSplit, ruleValueSplit1);
                    //如果为true满足可以提交
                    if (!compareDateTimes) {
                        Boolean executeAction = dimensionSDO.getExecuteAction();
                        if (executeAction) {
                            throw new FunctionException("OTS-04-001-00-15-048");
                            // return "该时间范围内不允许修改，请联系订单员修改";
                        }
                    }
                }
            }
        }

        //批量释放每日库存分解占用（带事务控制）
        BatchReleaseDailyInvRequest batchReleaseDailyInvRequest = new BatchReleaseDailyInvRequest();
        batchReleaseDailyInvRequest.setReleasesList(new ArrayList<>());
        for (ForecastOrderLineSDO forecastOrderLineSDO : orderLineSDOList) {
            Map features = forecastOrderLineSDO.getFeatures();
            if (MapUtils.isEmpty(features)
                    ||Objects.isNull(features.get(ALLOTLINEID))
                    ||StringUtils.isBlank(String.valueOf(features.get(ALLOTLINEID)))
                    ||Objects.isNull(features.get(DISINTEGRATION_QTY))
                    ||0==Integer.parseInt(String.valueOf(features.get(DISINTEGRATION_QTY)))
            ){
            continue;
            }
            ReleaseDailyInvRequest releaseDailyInvRequest = new ReleaseDailyInvRequest();
            releaseDailyInvRequest.setAllotLineId(String.valueOf(features.get(ALLOTLINEID)));
            releaseDailyInvRequest.setReleaseQuantity(String.valueOf(features.get(DISINTEGRATION_QTY)));
            batchReleaseDailyInvRequest.getReleasesList().add(releaseDailyInvRequest);
        }


        if (CollectionUtils.isNotEmpty(batchReleaseDailyInvRequest.getReleasesList())){
            Result<Boolean> releaseResult = inventoryAllotLineWriteService.batchRelease(batchReleaseDailyInvRequest);
            if (Objects.isNull(releaseResult)||!releaseResult.getResult()||!releaseResult.isSuccess()){
                throw new FunctionException("OTS-04-001-00-15-051","批量释放库存失败!");
            }
        }

        //删除子单状态判断
        Map<Long,Integer> existLineOrderStatusMap = getForecastLineMainStatus(orderLineSDOList);
        for (String id : ids) {
            Integer lineStatus = existLineOrderStatusMap.get(Long.parseLong(id));
            if (!CAN_DEL_FORECAST_STATUS.contains(lineStatus)){
                throw new FunctionException("OTS-04-001-00-15-058","批量删除预报子单失败！子单不允许删除！");
               }
        }

        //删除子订单
        DeleteForecastLineDetailRequest request = new DeleteForecastLineDetailRequest();
        request.setIds(ids);
        Integer count = forecastOrderLineWriteRepository.deleteForecastLine(request);
        if (Objects.isNull(count)||ids.size()!=count){
            throw new FunctionException("OTS-04-001-00-15-052","批量删除预报子单失败！");
        }


        return Result.success(new DeleteForecastLineDetailReponse(){{setCount(count);}});
    }

    @NotNull
    private Map<Long, Integer> getForecastLineMainStatus(List<ForecastOrderLineSDO> orderLineSDOList) {
        Map<Long, Integer> lineStatusMap=new HashMap<>();
        List<String> mainIds = orderLineSDOList.stream().map(ForecastOrderLineSDO::getMainOrderId).distinct().collect(Collectors.toList());
        List<ForecastOrderSDO> listPageResult = forecastOrderQueryRepository.batchQueryForecastOrder(mainIds);
        if (CollectionUtils.isNotEmpty(listPageResult)){
            Map<String, Integer> mainOrderStatus = listPageResult.stream().collect(Collectors.toMap(ForecastOrderSDO::getId, ForecastOrderSDO::getStatus));
            for (ForecastOrderLineSDO forecastOrderLineSDO : orderLineSDOList) {
                String mainOrderId = forecastOrderLineSDO.getMainOrderId();
                lineStatusMap.put(forecastOrderLineSDO.getId(),mainOrderStatus.getOrDefault(mainOrderId,ForecastStatusEnum.DRAFT.getNumValue()));
            }
        }
        return lineStatusMap;
    }

    @Override
    public Result<Integer> updateLineByBizId(UpdateLineByBizIdRequest updateForecastQtyRequest){
        if (CollectionUtils.isEmpty(updateForecastQtyRequest.getRequest())){
            throw new FunctionException("OTS-04-001-00-15-053","批量修改子单失败！");
        }
        int i = 0;
        for (BatchUpdateForAnalysisDTO batchUpdateForAnalysisDTO : updateForecastQtyRequest.getRequest()) {
            Boolean update = forecastOrderLineWriteRepository.batchUpdateForAnalysingByBiz(batchUpdateForAnalysisDTO);
            if (Objects.nonNull(update)&&update){
                i++;
            }
        }

        return Result.success(i);
    }

    @Override
    public Result<Integer> updateAnalysisDateByBiz(UpdateAnalysisDateByBizRequest updateAnalysisDateByBizRequest) {
        if (CollectionUtils.isEmpty(updateAnalysisDateByBizRequest.getRequest())){
            throw new FunctionException("OTS-04-001-00-15-054","批量修改子单失败！");
        }
        int i = 0;
        for (UpdateForAnalysisDataDTO batchUpdateForAnalysisDTO : updateAnalysisDateByBizRequest.getRequest()) {
            Boolean update = forecastOrderLineWriteRepository.updateForAnalysisDataByBiz(batchUpdateForAnalysisDTO);
            if (Objects.nonNull(update)&&update){
                i++;
            }
        }

        return Result.success(i);
    }

    @Override
    public Result<Integer> updateBizFeaturesDateByBiz(UpdateBizFeaturesDateByBizRequest updateBizFeaturesDateByBizRequest){

        if (CollectionUtils.isEmpty(updateBizFeaturesDateByBizRequest.getRequest())){
            throw new FunctionException("OTS-04-001-00-15-054","批量修改子单失败！");
        }
        int i = 0;
        for (UpdateForAnalysisDataDTO batchUpdateForAnalysisDTO : updateBizFeaturesDateByBizRequest.getRequest()) {
            Boolean update = forecastOrderLineWriteRepository.updateBizFeaturesByBiz(batchUpdateForAnalysisDTO);
            if (Objects.nonNull(update)&&update){
                i++;
            }
        }

        return Result.success(i);

    }

}
